package work;

import work.topo.*;
import mpi.*;


public class Communicator {
	private ProcessTopology topo;

	public Communicator(ProcessTopology topo) {
		this.topo = topo;
	}

	public ProcessTopology topology() {
		return topo;
	}

	public <T> Request send(T []buf) {
		Request r = null;

		if(buf == null || buf.length == 0) {
			return r;
		}
															//offset//length//type   //dest//tag
		r = MPI.COMM_WORLD.Isend(buf, 0, buf.length, MPI.OBJECT, topo.getSendTarget(), 1);

		return r;
	}
	public <T> Status finishSend(Request r) {
		Status stats = null;

		stats = r.Wait();

		return stats;
	}

	public <T> Request recv(T []buf) {
		Request r = null;

		if(buf == null || buf.length == 0) {
			return r;
		}
															//offset//length//type   //dest//tag
		r = MPI.COMM_WORLD.Irecv(buf,0,buf.length,MPI.OBJECT,topo.getRecvTarget(),1);
		return r;
	}
	public <T> Status finishRecv(Request r) {
		Status stats = null;

		stats = r.Wait();

		return stats;
	}



	public <T> Status finishComm(Request r) {
		Status stats = null;

		stats = r.Wait();

		return stats;
	}

	public void work() {
		Configurator cfg = Configurator.cfg();
		cfg.register(WorkThread.class);
		WorkThread w = cfg.get(WorkThread.class);

		w.start();
	}

	public String toString() {
		return "me = " + topo.me() + ",size = " + topo.size();
	}

	public class WorkThread extends Thread {
		public WorkThread() {
		}
		public void run() {
			System.out.println("Communicator.workthread for " + topo.me() + " started");
		}

		public String toString() {
			return "WorkerThread...";
		}
	}

}
